#include <cstdlib>
#include <iostream>
#include <conio.h>
#include <fstream>
#include <list>
#include <sstream>
#include <ctime>

//#define LINUX        //IF you are compiling under LINUX or other OS please
                       //Comment the #define WINDOWS and uncomment your OS
#define WINDOWS
//#define OSX


using namespace std;

extern void logHandler(int accNum, int action, int amount, bool result, string bg);
extern string int2Str(int number);

    char Clear[] = "cls";
    char ClearL[] = "clear";
    #ifdef WINDOWS
    char *Cls = Clear;
    #include <time.h>
    #else
    #ifdef LINUX
    char *Cls = ClearL;
    #include <time.h>
    #endif
    #endif


void PrintDate()
{
     #ifdef WINDOWS
     char dateStr [9];
     char timeStr [9];
     _strdate( dateStr);
     _strtime( timeStr );
     cout << "Today's date: " << dateStr << endl;
     cout << "Time: " << timeStr << endl;
     #else
     #ifdef LINUX
     time_t result;
     result = time(NULL);
     struct tm* brokentime = localtime(&result);
     cout << asctime(brokentime) << endl;
     #endif
     #endif
}

string itos(int number)
{
    string temp;
    stringstream strStream;
    strStream << number;
    temp = strStream.str();
    return temp;
}

class Bank
{
      public:
             void userHandler(int actionType, string bkImg);
             void yAd(); //Finished
      private:
              bool CheckAccess(); //Finished
              void CheckBalance();
              void Withdraw(); //Finished
              void Deposit(); //Finished
              void SetAccount(); //Finished
              void SaveAcc(); //Finished
              void OpenAcc(); //Finished
              void Print(int Type, int Amount); //Finished
              void Encrypt();
              void Decrypt();
              void mAd();
              int AccNum,Pass;  //---------|
              int Balance;               //|
              string Acc;                //| Var
              int AccNum_Enc,Pass_Enc;   //|
              int Balance_Enc;           //|
              string img;                //|
              string Amount;             //|
              string Pwd;       //---------|

};



void Bank::userHandler(int actionType, string bkImg)
{
    img = bkImg;
    switch(actionType)
    {
        case 0:
            SetAccount();
        break;
        case 1:
            CheckBalance();
        break;
        case 2:
            Withdraw();
        break;
        case 3:
            Deposit();
        break;
        case 4:
            mAd();
        break;
        default:
            exit(1);
    }
}

void Bank::CheckBalance()
{
    char Pt;
    system("cls");
    yAd();
    CheckAccess();
    logHandler(atoi(Acc.c_str()),2,atoi(Amount.c_str()),false,img);
    system("cls");
    yAd();
    cout << "\tYour account number is:" << Acc << endl;
    cout << "\tYour account balance is:" << Balance << endl;
    cout << "Print Recipt? (Y/N)" << endl;
    cin >> Pt;
    if((Pt == 'Y') ||(Pt == 'y'))
    {
        Print(2,atoi(Amount.c_str()));
    }
    system("cls");
}



void Bank::Decrypt()
{
     string temp;
     string temp2;
             AccNum = AccNum_Enc ^ Pass;
             Pass = Pass_Enc ^ 18;
             Balance = Balance_Enc ^ Pass;
             /*temp = XOR(AccNum_Enc,Pwd);
             AccNum = atoi(base64_decode(temp).c_str());

             temp = XOR(Pass_Enc,Pwd);
             Pass = atoi(base64_decode(temp).c_str());

             temp = XOR(Balance_Enc,Pwd);
             Balance = atoi(base64_decode(temp).c_str());*/
}

void Bank::Encrypt()
{
     string temp;
     string temp2;
     //Pwd = int2Str(Pass);
             AccNum_Enc = AccNum ^ Pass;
             Pass_Enc = Pass ^ 18;
             Balance_Enc = Balance ^ Pass;
             /*
             temp = base64_encode(reinterpret_cast<const unsigned char*>(int2Str(AccNum).c_str()), int2Str(AccNum).length());
             AccNum_Enc = XOR(temp,Pwd);

             temp = base64_encode(reinterpret_cast<const unsigned char*>(int2Str(Pass).c_str()), int2Str(Pass).length());
             Pass_Enc = XOR(temp,Pwd);

             temp = base64_encode(reinterpret_cast<const unsigned char*>(int2Str(Balance).c_str()), int2Str(Balance).length());
             Balance_Enc = XOR(temp,Pwd);*/
}



void Bank::Deposit()
{
     srand(time(NULL));
     string arg;
     int waitTime(0);
     waitTime = rand() % 10 + 1;
     Amount = "";
     char Pt;
     system(Cls);
     yAd();
     if(!CheckAccess())
     return;
     getAmount:
     cout << "Please input your amount of deposit: ";
     char Buffer = '\n';
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(Amount.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            Amount.erase(Amount.size()-1);
          }
     }
      if(isdigit(Buffer))
     {
        Amount += Buffer;
        cout << Buffer;
     }
    }
     //cin >> Amount;
     if(atol(Amount.c_str()) < 0)
     {
        cout << "\nPlease enter a non negitive value" << endl;
        logHandler(AccNum,3,atoi(Amount.c_str()),false,img);
        goto getAmount;
     }
     //Balance += atol(Amount.c_str());
     //SaveAcc();
     arg = "start atmArg.exe " + Acc + " " + itos(Pass) + " " + Amount + " " + itos(waitTime);
     //cout << endl << arg << endl;
     cout << "\nDeposit Successful" << endl;
     cout << "Please wait...We are processing your transaction." << endl;
     cout << "This will take 1-10 minutes" << endl;
     system(arg.c_str());
     logHandler(AccNum,3,atol(Amount.c_str()),true,img);
     cout << "Print Recipt? (Y/N)" << endl;
     cin >> Pt;
     if((Pt == 'Y') ||(Pt == 'y'))
     {
            Print(0,atoi(Amount.c_str()));
     }
}

void Bank::Withdraw()
{
     Amount = "";
     char Pt;
     system(Cls);
     yAd();
     if(!CheckAccess())
     return;
     getAmount:
     cout << "Please input the amount of your withdraw: ";
     char Buffer = '\n';
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(Amount.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            Amount.erase(Amount.size()-1);
          }
     }
      if(isdigit(Buffer))
     {
        Amount += Buffer;
        cout << Buffer;
     }
    }
     //cin >> Amount;
     if(atoi(Amount.c_str()) > Balance)
     {
        cout << "\nNon-sufficient funds to complete withdraw" << endl;
        logHandler(AccNum,2,atoi(Amount.c_str()),false,img);
        system("pause");
        goto getAmount;
     }
     Balance -= atoi(Amount.c_str());
     SaveAcc();
     cout << "\nWithdraw Successful" << endl;
     logHandler(AccNum,2,atoi(Amount.c_str()),true,img);
     cout << "Print Recipt? (Y/N)" << endl;
     cin >> Pt;
     if((Pt == 'Y') ||(Pt == 'y'))
     {
            Print(1,atoi(Amount.c_str()));
     }
}

void Bank::Print(int Type, int Amount)
{
     #ifdef WINDOWS
     char dateStr [9];
     char timeStr [9];
     _strdate( dateStr);
     _strtime( timeStr );
     //cout << "Today's date: " << dateStr << endl;
     //cout << "Time: " << timeStr << endl;
     #else
     #ifdef LINUX
     time_t result;
     result = time(NULL);
     struct tm* brokentime = localtime(&result);
     cout << asctime(brokentime) << endl;
     #endif
     #endif
     ofstream Log;
     system("del /f /q recipt.txt");
     switch(Type)
     {
                 case 0:
                      Log.open("recipt.txt");
                      Log << "***************************************" << endl;
                      Log << "        Welcome to Mars Bank" << endl;
                      Log << "        The first Bank on Mars." << endl;
                      Log << "=======================================" << endl;
                      Log << "Language: English" << endl;
                      Log << "Service: Deposit" << endl;
                      Log << "Account Number: " << AccNum << endl;
                      Log << "Amount: " << Amount << endl;
                      Log << "Date: " << dateStr << endl;
                      Log << "Time: " << timeStr << endl;
                      Log << "=======================================" << endl;
                      Log << "Project Home Page: caccatm.codeplex.com" << endl;
                      Log.close();
                      system("NOTEPAD /P recipt.txt");
                      break;
                 case 1:
                      Log.open("recipt.txt");
                      Log << "***************************************" << endl;
                      Log << "        Welcome to Mars Bank" << endl;
                      Log << "        The first Bank on Mars." << endl;
                      Log << "=======================================" << endl;
                      Log << "Language: English" << endl;
                      Log << "Service: Withdraw" << endl;
                      Log << "Account Number: " << AccNum << endl;
                      Log << "Amount: " << Amount << endl;
                      Log << "Date: " << dateStr << endl;
                      Log << "Time: " << timeStr << endl;
                      Log << "=======================================" << endl;
                      Log << "Project Home Page: caccatm.codeplex.com" << endl;
                      Log.close();
                      system("NOTEPAD /P recipt.txt");
                      break;
                 case 2:
                      Log.open("recipt.txt");
                      Log << "=======================================" << endl;
                      Log << "Language: English" << endl;
                      Log << "Service: Check Balance" << endl;
                      Log << "Account Number: " << AccNum << endl;
                      Log << "Amount: $" << Amount << endl;
                      Log << "Date: " << dateStr << endl;
                      Log << "Time: " << timeStr << endl;
                      Log << "=======================================" << endl;
                      Log << "Project Home Page: caccatm.codeplex.com" << endl;
                      Log.close();
                      system("NOTEPAD /P recipt.txt");
                      break;
                 default:
                         cout << "Unknown Error!" << endl;
     }
}

void Bank::SaveAcc()
{
     Encrypt();
     ofstream Save;
     //cout << "Save:" << (Acc + ".mb").c_str()<< endl;
     Save.open((Acc + ".mb").c_str());
     Save << Balance_Enc << endl;
     Save << AccNum_Enc << endl;
     Save << Pass_Enc << endl;
     Save.close();
}

void Bank::OpenAcc()
{
               ifstream Read((Acc + ".mb").c_str(),ios::in);
               if(!Read.is_open())
               {
                 cout << "Wrong Account Number, Please try again!" << endl;
                 logHandler(atoi(Acc.c_str()),4,atoi(Amount.c_str()),false,img);
                 Read.close();
                 CheckAccess();
               }
               Read >> Balance_Enc;
               Read >> AccNum_Enc;
               Read >> Pass_Enc;

               //string temp = base64_encode(reinterpret_cast<const unsigned char*>(Pwd.c_str()), Pwd.length());
               //string pwdPass_Enc = XOR(temp,Pwd);
               if(Pass_Enc != (atoi(Pwd.c_str())^18))
               //if(Pass_Enc != pwdPass_Enc)
               {
                    cout << "Wrong Password! Try again!" << endl;
                    logHandler(atoi(Acc.c_str()),4,atoi(Amount.c_str()),false,img);
                    CheckAccess();
               }
               else
               {
                   logHandler(atoi(Acc.c_str()),4,atoi(Amount.c_str()),true,img);
                   Decrypt();
               }

}

bool Bank::CheckAccess()
{
     char Buffer;
     Buffer = '\n';
     Acc = ""; Pwd = "";
     cout << "Please input your Account number (0 to quit): ";
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(Acc.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            Acc.erase(Acc.size()-1);
          }
     }
      if(isdigit(Buffer))
     {
        Acc += Buffer;
        cout << "*";
     }
    }
     cout << endl;
     if(Acc == "0")
     {
         system("cls");
         return false;
     }
     Buffer = '\n';
     cout << "Please input your password: ";
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(Pwd.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            Pwd.erase(Pwd.size()-1);
          }
     }
      if(isdigit(Buffer))
       {
        Pwd += Buffer;
        cout << "*";
       }
    }
     cout << endl;
     OpenAcc();
     return true;
}

void Bank::SetAccount()
{
     ifstream test;
     string TempAcc = "",TempPass = "";
     string TempAcc2 = "",TempPass2 = "";
     char Buffer;
     system(Cls);
     yAd();
     getAcc:
     Buffer = '\n';
     TempAcc = ""; TempAcc2 = "";
     cout << "Please choose input your desired account number (xxxxx) (0 to quit): ";
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(TempAcc.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            TempAcc.erase(TempAcc.size()-1);
          }
       }
      if(isdigit(Buffer))
       {
        TempAcc += Buffer;
        cout << "*";
       }
    }
     cout << endl;
     Acc = TempAcc;
     if(TempAcc == "0")
     {
         system("cls");
         return;
     }
     if(TempAcc.size() != 5)
     {
        cout << "The account number must be 5 digits" << endl;
        logHandler(atoi(TempAcc.c_str()),0,0,false,img);
        goto getAcc;
     }
     test.open((TempAcc + ".mb").c_str());
     if(test)
     {
        cout << "The account alerady exist, please input a new number\n";
        logHandler(atoi(TempAcc.c_str()),0,0,false,img);
        goto getAcc;
     }
     if(TempAcc == "00000")
     {
         cout << "NON ZERO account number please!" << endl;
         goto getAcc;
     }

     //question: would here be a good place to check if AccNum is already a account?

     cout << "Please comfirm: ";
     Buffer = '\n';
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(TempAcc2.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            TempAcc2.erase(TempAcc2.size()-1);
          }
     }
      if(isdigit(Buffer))
       {
        TempAcc2 += Buffer;
        cout << "*";
       }
    }
     cout << endl;
     if(atoi(TempAcc.c_str()) != atoi(TempAcc2.c_str())){
     cout << "Please try again!" << endl;
     logHandler(atoi(TempAcc2.c_str()),0,0,false,img);
     goto getAcc;
     }
     AccNum = atoi(TempAcc.c_str());

     getPass:
     TempPass = ""; TempPass2 = "";
     Buffer = '\n';
     cout << "Please input your password: ";
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(TempPass.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            TempPass.erase(TempPass.size()-1);
          }
     }
      if(isdigit(Buffer))
       {
        TempPass += Buffer;
        cout << "*";
       }
    }
     cout << endl;
     Pwd = TempPass;
     if(Pwd.size() != 5)
     {
        cout << "The password must be 5 digit" << endl;
        logHandler(atoi(TempAcc.c_str()),0,0,false,img);
        goto getPass;
     }
     Buffer = '\n';
     cout << "Please comfirm: ";
     while(Buffer != 13) //Loop until 'Enter' is pressed
     {
       Buffer = _getch();
       if(Buffer == 13)
       break;
       if(Buffer == 8)
       {
        if(TempPass2.size()!=0)   //delete only if there is input
          {
            cout<<"\b \b";
            TempPass2.erase(TempPass2.size()-1);
          }
       }
      if(isdigit(Buffer))
       {
        TempPass2 += Buffer;
        cout << "*";
       }
    }
     cout << endl;
     if(atoi(TempPass.c_str()) != atoi(TempPass2.c_str())){
     cout << "Please try again!" << endl;
     logHandler(atoi(TempAcc.c_str()),0,0,false,img);
     goto getPass;
     }
     Pass = atoi(TempPass.c_str());
     SaveAcc();
     system(Cls);
     Balance = 0;
     cout << "Account created successful! Thank You" << endl;
     system("pause");
     logHandler(AccNum,0,0,true,img);
}

void Bank::mAd()
{
    char Pt = '\n';
    ofstream adFile;
    adFile.open("mAd.ad");
    system("cls");
    yAd();
    string line1 = "";
    string line2 = "";
    int size1;
    int size2;
    CheckAccess();
    cout << "This will cost you $1000 (Y/N)" << endl;
    cin >>Pt;
    if((Pt == 'Y') ||(Pt == 'y'))
     {
         if(Balance >= 1000)
         {
             Balance -= 1000;
             cin.clear();
             cout << "Please input your first line of ad (MAX=40):";
             getline(cin,line1);
             getline(cin,line1);
             cout << endl;
             size1 = line1.size();
             cout << "Please input your second line of ad (MAX=40):";
             getline(cin,line2);
             cout << endl;
             size2 = line2.size();
             adFile << "========================================" << endl;
             for(int i(0);i<((40-size1)/2);i++)
             adFile << " ";
             adFile << line1 << endl;
             for(int i(0);i<((40-size2)/2);i++)
             adFile << " ";
             adFile << line2 << endl;
             adFile << "====================================yAd=" << endl;
             adFile.close();
             cout << "Thank you! Your ad will show up in a minute." << endl;
             logHandler(atoi(Acc.c_str()),5,0,true,img);
             system("pause");
             system("cls");

         }
         else
         {
             cout << "Sorry, You don't have enough money." << endl;
             logHandler(atoi(Acc.c_str()),5,0,false,img);
         }
     }
     else
     {
         cout << "Thank you! Come back here later" << endl;
     }
}


void Bank::yAd()
{
     ifstream ad;
     string line;
     ad.open("mAd.ad",ios::in);
     switch(rand()%16+1)
     {
            case 1:
                 cout << "========================================" << endl;
                 cout << "  Setup a account now get $200 FREE    " << endl;
                 cout << "====================================yAD=" << endl;
            break;
            case 2:
                 cout << "========================================" << endl;
                 cout << "           Want Fast Food?            " << endl;
                 cout << "           Try 120% FatMac            " << endl;
                 cout << "====================================yAD=" << endl;
            break;
            case 3:
                 cout << "========================================" << endl;
                 cout << "      FREE Pizza at PanoraPizza!       " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 4:
                 cout << "========================================" << endl;
                 cout << "   Get your free coffee at CACC RM16   " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 5:
                 cout << "========================================" << endl;
                 cout << "          Tired? Try NUKE(tm)          " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 6:
                 cout << "========================================" << endl;
                 cout << "       Having problem study Math?      " << endl;
                 cout << "       Try qAi automated Calculator    " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 7:
                 cout << "========================================" << endl;
                 cout << "   Need to get 36 on ACT No Problem!   " << endl;
                 cout << " Take SuperACT Right now! FDA Approved " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 8:
                 cout << "========================================" << endl;
                 cout << "            Want a new car?            " << endl;
                 cout << "       check www.blackmarket.com       " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 9:
                 cout << "========================================" << endl;
                 cout << "            Register Now               " << endl;
                 cout << "    win a free trip to North Korea     " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 10:
                 cout << "========================================" << endl;
                 cout << "           Computer Problems?          " << endl;
                 cout << "      Check out downloadvirus.com      " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 11:
                 cout << "========================================" << endl;
                 cout << "   Open your Mars Bank account now!    " << endl;
                 cout << "      Check your local Mars Bank       " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 12:
                 cout << "========================================" << endl;
                 cout << "           Need Money fast ?           " << endl;
                 cout << "       Logon anythingformoney.com      " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 13:
                 cout << "========================================" << endl;
                 cout << "   Need a Cheap and secure computer?   " << endl;
                 cout << "    Buy Sac(tm) from Pineapple.inc     " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 14:
                 if(ad)
                 {
                    while (! ad.eof() )
                    {
                        getline (ad,line);
                        cout << line << endl;
                    }
                 }
                 else
                 {
                    cout << "========================================" << endl;
                    cout << "       Your Advertisement here         " << endl;
                    cout << "                                       " << endl;
                    cout << "====================================yAD=" << endl;
                 }
                 break;
            case 15:
                 cout << "========================================" << endl;
                 cout << "      Apply a Loan in Mars Bank        " << endl;
                 cout << "         As low as 250% APR            " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
            case 16:
                 cout << "========================================" << endl;
                 cout << "       Tired of study? No Problem!     " << endl;
                 cout << "   Try COMA(tm) Ultra-Comfort Pillow   " << endl;
                 cout << "    Guarentee you will never wake up   " << endl;
                 cout << "====================================yAD=" << endl;
                 break;
     }
}

